package com.alameda.facade.video;

import com.alameda.common.base.constant.MediaConstant;
import com.alameda.common.utils.CollectionUtils;
import com.alameda.media.api.AdMediaProvider;
import com.alameda.statement.api.AdSystemRecordProvider;
import com.alameda.statement.enums.AdSystemRecordEnum;
import com.alameda.tag.api.AdTagProvider;
import com.alameda.tag.vo.AdTagVO;
import com.alameda.type.api.AdMediaTypeProvider;
import com.alameda.type.vo.AdMediaTypeVO;
import com.alameda.video.dto.ApVideoDTO;
import com.alameda.video.vo.ApVideoVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.alameda.common.base.constant.MediaConstant.StringConstant.EMPTY_STRING;

/**
 * 移动端视频模块 接入层
 *
 * @author Lv
 * @date 2024/09/22
 */
@Component
public class ApVideoFacade {

    @DubboReference
    private AdMediaProvider adMediaProvider;

    /**
     * 查询视频列表
     *
     * @param apVideoDTO 移动端视频信息
     * @return
     */
    public List<ApVideoVO> loadVideo(ApVideoDTO apVideoDTO) {
        List<ApVideoVO> apVideoList = adMediaProvider.loadVideo(apVideoDTO);
        apVideoList.forEach(this::dealName);
        return apVideoList;
    }

    /**
     * 处理视频文件名称
     *
     * @param apVideoVO 频文件
     */
    public void dealName(ApVideoVO apVideoVO) {
        String dealResult = dealVideoName(apVideoVO.getVideoName());
        apVideoVO.setVideoName(dealResult);
    }

    /**
     * 视频文件名称截取
     *
     * @param videoName 视频文件名称
     * @return
     */
    public String dealVideoName(String videoName) {
        byte[] bytes = videoName.getBytes(StandardCharsets.UTF_8);
        return bytes.length > MediaConstant.LoadMediaConstant.DEAL_INDEX ? getExtractedName(videoName) : videoName;
    }

    /**
     * 获取截取后的视频文件名称
     *
     * @param videoName 视频文件名称
     * @return
     */
    private String getExtractedName(String videoName) {
        String extractedString = videoName.substring(0, Math.min(videoName.length(), 25));
        return extractedString + MediaConstant.LoadMediaConstant.REPLACE_STR;
    }

    /**
     * 查询视频
     *
     * @param apVideoDTO 移动端视频信息
     * @return
     */
    public ApVideoVO findById(ApVideoDTO apVideoDTO) {
        ApVideoVO apVideoVO = adMediaProvider.findById(apVideoDTO);
        dealApVideoInfo(apVideoVO);
        return apVideoVO;
    }

    /**
     * 处理封装物理存储名称以及物理存储基础路径 方便前端渲染
     *
     * @param apVideoVO 移动端视频数据显示对象
     */
    private void dealApVideoInfo(ApVideoVO apVideoVO) {
        String filePath = apVideoVO.getUrl();
        String[] split = filePath.split("/");
        // 解析出物理存储名称
        String physicalName = split[split.length - 1];
        // 解析出物理存储基础路径
        String physicalBasePath = filePath.replace(physicalName, "");
        apVideoVO.setPhysicalName(physicalName);
        apVideoVO.setPhysicalBasePath(physicalBasePath);
    }

    /**
     * 查询视频播放页面列表视频
     *
     * @param apVideoDTO 移动端视频信息
     * @return
     */
    public List<ApVideoVO> findVideoDetailInfo(ApVideoDTO apVideoDTO) {
        List<ApVideoVO> apVideoVOList = adMediaProvider.findVideoDetailInfo(apVideoDTO);
        apVideoVOList.forEach(this::dealName);
        return apVideoVOList;
    }

    @DubboReference
    private AdSystemRecordProvider adSystemRecordProvider;

    /**
     * 存储系统业务量记录
     *
     * @param adSystemRecordEnum 系统记录类型
     * @return
     */
    @Async
    public void saveRecord(AdSystemRecordEnum adSystemRecordEnum) {
        adSystemRecordProvider.saveRecord(adSystemRecordEnum);
    }

    @DubboReference
    private AdMediaTypeProvider adMediaTypeProvider;

    /**
     * 通过媒体id读取分类信息
     *
     * @param mediaId 媒体id
     * @return
     */
    public AdMediaTypeVO findTypeInfoByMediaId(Long mediaId) {
        AdMediaTypeVO adMediaTypeVO = adMediaTypeProvider.findTypeInfoByMediaId(mediaId);
        adMediaTypeVO = Optional.ofNullable(adMediaTypeVO).orElse(AdMediaTypeVO.builder().build());
        adMediaTypeVO.setTypeCoverUrl(EMPTY_STRING);
        return adMediaTypeVO;
    }

    @DubboReference
    private AdTagProvider adTagProvider;

    /**
     * 通过媒体id读取标签信息
     *
     * @param mediaId 媒体id
     * @return
     */
    public List<AdTagVO> findTagInfoByMediaId(Long mediaId) {
        List<AdTagVO> adTagVOList = adTagProvider.findTagInfoByMediaId(mediaId);

        return Optional.ofNullable(adTagVOList).orElse(CollectionUtils.newArrayList()).stream()
                .sorted(Comparator.comparing(AdTagVO::getCreateTime).reversed())
                .peek(item -> item.setTagCoverUrl(EMPTY_STRING))
                .collect(Collectors.toList());
    }
}
